using System;
using Project.Configs;
using Project.Models.Abstractions;
using Project.Utilities;
using Project.Utilities.Abstractions;

namespace Project.Models
{
    public class Character : IReadOnlyCharacter
    {
        private const string None = nameof(None);

        public Character(CharacterConfig config)
        {
            Name = config.Name;

            PointsToSpend = new ReactiveProperty<int>(value => Math.Clamp(value, 0, config.MaxPointsToSpendValue));

            StrengthPoints = new PrimaryStatPoints(config.StrengthPointsValue, config.MaxPrimaryStatPointsValue);
            AgilityPoints = new PrimaryStatPoints(config.AgilityPointsValue, config.MaxPrimaryStatPointsValue);
            IntelligencePoints = new PrimaryStatPoints(config.IntelligencePointsValue, config.MaxPrimaryStatPointsValue);

            HealthPoints = new SecondaryStatPoints(StrengthPoints, config.StrengthToHealthPointsMultiplier);
            ArmorPoints = new SecondaryStatPoints(AgilityPoints, config.AgilityToArmorPointsMultiplier);
            ManaPoints = new SecondaryStatPoints(IntelligencePoints, config.IntelligenceToManaPointsMultiplier);
        }

        public readonly string Name;

        public readonly ReactiveProperty<int> PointsToSpend;

        public readonly PrimaryStatPoints StrengthPoints;
        public readonly PrimaryStatPoints AgilityPoints;
        public readonly PrimaryStatPoints IntelligencePoints;

        public readonly SecondaryStatPoints HealthPoints;
        public readonly SecondaryStatPoints ArmorPoints;
        public readonly SecondaryStatPoints ManaPoints;

        string IReadOnlyCharacter.Name => Name;

        IReadOnlyReactiveProperty<int> IReadOnlyCharacter.PointsToSpend => PointsToSpend;

        IReadOnlyPrimaryStatPoints IReadOnlyCharacter.StrengthPoints => StrengthPoints;
        IReadOnlyPrimaryStatPoints IReadOnlyCharacter.AgilityPoints => AgilityPoints;
        IReadOnlyPrimaryStatPoints IReadOnlyCharacter.IntelligencePoints => IntelligencePoints;

        IReadOnlySecondaryStatPoints IReadOnlyCharacter.HealthPoints => HealthPoints;
        IReadOnlySecondaryStatPoints IReadOnlyCharacter.ArmorPoints => ArmorPoints;
        IReadOnlySecondaryStatPoints IReadOnlyCharacter.ManaPoints => ManaPoints;

        public void Reset()
        {
            PointsToSpend.Value = 0;

            StrengthPoints.Value = StrengthPoints.MinValue;
            AgilityPoints.Value = AgilityPoints.MinValue;
            IntelligencePoints.Value = IntelligencePoints.MinValue;

            HealthPoints.Value = 0;
            ArmorPoints.Value = 0;
            ManaPoints.Value = 0;
        }
    }
}
